/**
 * System.h
 */

#ifndef SYSTEM_H
#define SYSTEM_H

#include <string>
#include <vector>

#include <fstream>
#include <boost/serialization/vector.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>

#include "SystemPreferences.h"
#include "User.h"
#include "AppList.h"

/**
 * Represents the entry point of the core data.
 * Allows to handle users and app actions.
 * Each modification are NOT saved into configuration file
 * be careful of calling right method to save to a file
 */
class System {
public:
  /**
   * Constructor (default)
   */
  System();

  /**
   * Constructor (with args from main)
   * @param argc argc from main
   * @param argv argv from main
   */
  System(int argc, char** argv);

  /**
   * Factory that create an instance from a configuration file
   * @param file full path of the configuration file
   */
  static System* SystemFactory(std::string file);

  /**
   * Destructor
   */
  virtual ~System();

  /**
   * Set the system preferences
   * @param prefs specified preferences
   */
  void setPreferences(SystemPreferences* prefs);

  /**
   * Return the system preferences
   */
  SystemPreferences& getPreferences();

  /**
   * Add an existing user in the system
   * @param user new coming user
   */
  void addUser(User* user);

  /**
   * Add user from serialized file
   * @param file input serialized file where user is registred
   */
  void addUser(std::string file);

  /**
   * Remove the user from the system
   * @param user user to remove
   */
  void removeUser(User* user);

  /**
   * Change the currently connected user
   * @param user the user that is connected
   */
  void setConnectedUser(User& user);

  /**
   * Get the currently connected user
   * @returns currently connected user
   */
  User& getConnectedUser();

  /**
   * Get the AppList of the currently connected user
   * @returns the AppList of the currently connected user
   */
  AppList* getConnectedUserAppList();

  /**
   * Save the system configuration to a file
   * @param file the full path where the file will be saved
   */
  void saveConfiguration(std::string file);

private:
  friend class boost::serialization::access;
  template<class Archive>
  /**
   * Saves the preference or load preferences to / from an archive
   */
  void serialize(Archive & ar, const unsigned int version);

  /**
   * System preferences
   */
  SystemPreferences* _sysprefs;

  /**
   * Contains all registered users in the system
   */
  std::vector<User*> _users;

  /**
   * Current connected user in the system
   */
  User* _connected;
};

#endif
